/********************************************************************************
 * CommonFunctionDelegator.java
 *
 * Created by Ravi Pandya
 * Last modified Date: September 15, 2008 11:13:51 AM by Ravi
 * Version : 0.1
 * Copyright (c) 2008 - 2009 cyberThink Infotech Pvt. Ltd., All rights reserved.
 ********************************************************************************/

package com.printeverywhere.delegator;

import static com.printeverywhere.util.AttributeConstants.CLOSING_SESSION;
import static com.printeverywhere.util.LoggerConstants.USERLISTEXCEPTION;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.printeverywhere.dto.Items;
import com.printeverywhere.util.HibernateUtil;
import com.printeverywhere.util.SearchCriteria;

public class CommonFunctionDelegator {

	private static Logger log = Logger.getLogger(FeedbackServiceDelegator.class);

	public static List<?> getObjectBySearchCriteria(SearchCriteria searchCriteria, Class<?> cls) {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(cls);
		String orderBY = searchCriteria.getOrderBy();
		if (orderBY != null) {
			if (searchCriteria.isAsc()) {
				criteria.addOrder(Order.asc(orderBY));
			} else {
				criteria.addOrder(Order.desc(orderBY));
			}
		}
		Set<String> keys = searchCriteria.getAttributeNames();
		Iterator<String> it = keys.iterator();
		String key = null;
		Object value = null;
		while (it.hasNext()) {
			key = it.next();
			value = searchCriteria.getAttribute(key);
			criteria.add(Restrictions.eq(key, value));
		}
		Transaction transaction = session.beginTransaction();
		List<?> list;
		try {
			list = criteria.list();
			transaction.commit();
		} catch (HibernateException e) {
			log.error(USERLISTEXCEPTION);
			throw e;
		} finally {
			if(log.isInfoEnabled()){
				log.info(CLOSING_SESSION);
			}
			session.flush();
			HibernateUtil.closeSession();
		}
		return list;
	}

	/**
	 * This is General Insert method
	 *
	 * @param obj
	 *
	 * @return the null
	 *
	 * @throws HibernateException the hibernate exception
	 *
	 * This method will take a obj as a parameter. it will
	 * automatically cast that object into perticular table
	 * and it will insert that obj in database using hibernate.
	 */

	public static void generalInsertbyobj(Object obj) throws HibernateException	{
		if(log.isInfoEnabled()){
			log.info("General Insert Started".intern());
		}
		Session session = HibernateUtil.getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			session.saveOrUpdate(obj);
			tx.commit();
		} catch (RuntimeException e) {
			log.error("Got exception when General insert ".intern() + e);
			if (tx != null)
				tx.rollback();
			if(session != null) {
				session.flush();
				session.close();
			}
			throw e;
		} catch(Exception ex) {
			log.error("Got exception when General insert ".intern() + ex);
			if (tx != null)
				tx.rollback();
			if(session != null) {
				session.flush();
				session.close();
			}
		}finally {
			if(log.isInfoEnabled()){
				log.info("Closing session".intern());
			}
			tx = null;
			session.flush();
			session.close();
		}
		log.info("General Insert Finished".intern());
	}

	/**
	 * This is General Update method
	 *
	 * @param obj
	 *
	 * @return the null
	 *
	 * @throws HibernateException the hibernate exception
	 *
	 * This method will take a obj as a parameter. it will
	 * automatically cast that object into perticular table
	 * and it will insert that obj in database using hibernate.
	 */
	public static void generalUpdatebyobj(Object obj) throws HibernateException {
		if(log.isInfoEnabled()){
			log.info("General Insert Started".intern());
		}
		Session session = HibernateUtil.getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			session.update(obj);
			tx.commit();
		} catch (RuntimeException e) {
			log.error("Got exception when General Update ".intern());
			if (tx != null)
				tx.rollback();
			throw e;
		} finally {
			if(log.isInfoEnabled()){
				log.info("Closing session".intern());
			}
			session.flush();
			session.close();
		}
		log.info("General Update Finished".intern());
	}

	public static void GeneralDelete(Object obj) {
		if(log.isInfoEnabled()){
			log.info("General Delete Started".intern());
		}
		Session session = HibernateUtil.getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			session.delete(obj);
			tx.commit();
		} catch (RuntimeException e) {
			log.error("Got exception when General Delete ".intern());
			if (tx != null)
				tx.rollback();
			throw e;
		} finally {
			if(log.isInfoEnabled()){
				log.info("Closing session".intern());
			}
			session.flush();
			session.close();
		}
		log.info("General Delete Finished".intern());
	}

	public static List<?> getAllfromtable(String classname) throws HibernateException {
		List allfromtable = new ArrayList();
		if(log.isInfoEnabled()){
			log.info("General get allFrom Table Started".intern());
		}
		Session session = HibernateUtil.getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Class.forName(classname);
			allfromtable = session.createCriteria(Class.forName(classname)).list();
			tx.commit();
			return allfromtable;
		} catch (RuntimeException e) {
			log.error("Got exception when General Update ".intern());
			if (tx != null)
				tx.rollback();
			throw e;
		} catch (Exception e) {
			log.error("Got exception when General Update ".intern());
			if (tx != null)
				tx.rollback();
		} finally {
			if(log.isInfoEnabled()){
				log.info("Closing session".intern());
			}
			session.flush();
			session.close();
		}
		log.info("General get allFrom Table Finished".intern());
		return allfromtable;
	}

	public static List<?> Getsomethingusingsomething(String classname, String parameter) throws HibernateException {

		List result = new ArrayList();
		if(log.isInfoEnabled()){
			log.info("General something using something Started".intern());
		}
		Session session = HibernateUtil.getSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Class.forName(classname);
			Criteria criteria = session.createCriteria(Class.forName(classname));
			criteria.add(Restrictions.eq(parameter ,parameter));
			result = criteria.list();
			tx.commit();
			return result;
		} catch (RuntimeException e) {
			log.error("Got exception when General Update ".intern());
			if (tx != null)
				tx.rollback();
			throw e;
		} catch (Exception e) {
			log.error("Got exception when General Update ".intern());
			if (tx != null)
				tx.rollback();
		} finally {
			if(log.isInfoEnabled()){
				log.info("Closing session".intern());
			}
			session.flush();
			session.close();
		}
		log.info("General something using something Finished".intern());
		return result;
	}

	public static List GeneralgetCriteriaList(String classname, SearchCriteria searchCriteria)throws HibernateException {
		if(log.isInfoEnabled()){
			log.info("General General get Criterail List Started".intern());
		}
		Session session = HibernateUtil.getSession();
		Criteria criteria = null;

		try {
			criteria = session.createCriteria(Class.forName(classname));
		} catch (ClassNotFoundException e1) {
			log.error("Got exception at getCriteriaList ".intern());
			e1.printStackTrace();
		}
		String orderBY = searchCriteria.getOrderBy();
		if (orderBY != null) {
			if (searchCriteria.isAsc()) {
				criteria.addOrder(Order.asc(orderBY));
			} else {
				criteria.addOrder(Order.desc(orderBY));
			}
		}
		Set<String> keys = searchCriteria.getAttributeNames();
		Iterator<String> it = keys.iterator();
		String key = null;
		Object value = null;
		while (it.hasNext()) {
			key = it.next();
			value = searchCriteria.getAttribute(key);
			criteria.add(Restrictions.eq(key, value));
		}
		Transaction transaction = session.beginTransaction();
		List list;
		try {
			list = criteria.list();
			transaction.commit();
		} catch (HibernateException e) {
			log.error("Got exception when gEBERAL getting list with search criteria".intern());
			throw e;
		} finally {
			if(log.isInfoEnabled()){
				log.info("Closing session".intern());
			}
			session.flush();
			HibernateUtil.closeSession();
		}
		log.info("General General get Criterail List finished".intern());
		return list;
	}

	public static int executeQuery(String hql) {
		Session session = HibernateUtil.getSession();
		Query query = session.createQuery(hql);
	    return query.executeUpdate();
	}

	public static List executeSQLQuery(String sqlQuery) {
		Session session = HibernateUtil.getSession();
		Query query = session.createSQLQuery(sqlQuery);
		return query.list();
	}

	public static void main(String[] args) {
		SearchCriteria searchCriteria = new SearchCriteria();
		searchCriteria.setAttribute("itemId", 1);
		List<Items> items = (List<Items>) CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, Items.class);

	}

}